/**
 * This is a work in progress. Right now it is incredibly simple
 * because its objectives are hazily defined. Once the certificate
 * structure is finished, this can be fleshed out.
 * @author Henry Mozer
 */
function Storage() {
	// PRIVATE
	// For convenience, what we want to manipulate
	var storage = chrome.storage.local;
	
	chrome.extension.onMessage.addListener(function(request, sender, sendResponse){
        switch(request.message){
			// A page was visited
			case "PageVisited":
				// request.hostname will get you the hostname of the link or page
			 	break;
				
			// A link was detected
			case "LinkDetected":
				break;
				
			// A link was converted to HTTPS
			case "LinkSecure":
				setCert(request.hostname, true);
				break;
				
			// A link could not be converted to HTTPS
			case "LinkInsecure":
				setCert(request.hostname, false);
				break;
				
			// A link was already using HTTPS
			case "LinkAlreadySecure":
				setCert(request.hostname, true);
				break;
		}
	});

	// Makes sure the certificates object exists
	storage.get('certificates', function(items) {
		if (!items.certificates) {
			var certs = new Object();
			certs.unique = 0;
			certs.total  = 0;
			certs.failed = 0;
			storage.set({'certificates': certs});
		}
	});

	// PUBLIC
	this.getCert = function(url) {
		// TODO: hash
		console.log("Getting " + url);
		var obj;
		storage.get('certificates', function(items) {
			obj = items.certificates[url];
			if (obj != undefined) {
				items.certificates.total = items.certificates.total + 1;
			}
			storage.set({'certificates': certs});
		});
		return obj;
	};

	var setCert = function(url, cert) {
		// TODO: hash
		storage.get('certificates', function(items){
			console.log("Setting " + url + " to " + cert);
			var certs = items.certificates;
			if (certs[url] == undefined) {
				certs.unique = certs.unique + 1;
			} else if (!cert) {
				certs.failed = certs.failed + 1;
			}
			certs.total = certs.total + 1;
			certs[url] = cert;
			storage.set({'certificates': certs});
		});
		return;
	};

	this.clearCerts = function() {
		storage.get('certificates', function(items){
			delete items.certificates;
			var certs = new Object();
			certs.unique = 0;
			certs.total  = 0;
			certs.failed = 0;
			items.certificates = certs;
			storage.set({"certificates": certs});
		});
	};

	this.getUniques = function(varToSet) {
		storage.get('certificates', function(items) {
			console.log("Reading uniques: " + items.certificates.unique);
			varToSet.innerHTML = items.certificates.unique;
		});
	};

	this.getTotal = function(varToSet) {
		storage.get('certificates', function(items) {
			console.log("Reading total: " + items.certificates.total);
			varToSet.innerHTML = items.certificates.total;
		});
	};

	this.getSuccessRate = function(varToSet) {
		var n = 0;
		storage.get('certificates', function(items) {
			if (items.certificates.total) {
				n = items.certificates.failed / items.certificates.total;
			} else {
				n = 0;
			}
			varToSet.innerHTML = Math.round(100 - 100*n) + "%";
		});
	};

	this.clearStats = function() {
		storage.get('certificates', function(items) {
			items.certificates.failed = 0;
			items.certificates.total = 0;
			items.certificates.unique = 0;
		});
	};

	this.toString = function() {
		//for cert in storage {
		//	storage[cert];
		//}
		return "Not implemented yet,\nwaiting on certificate structure.";
	};
    
    
    /**
     * Gets the specified variable from local storage.
     * Note: This implementation requires Storage to be declared as a Background script.
     * @author Daniel Fairweather
     * @param key The index you wish to get from local storage.
     * @returns The value of the specified index in local storage.
     */
    this.get = function(key){
        if(this.exists(key)){
            var item = localStorage.getItem(key);
            return(JSON.parse(item).value);
        }
        else{
            return(null);
        }
    }
    
    
    
    /**
     * Sets the specified variable and value in local storage.
     * Note: This implementation requires Storage to be declared as a Background script.
     * @author Daniel Fairweather
     * @param key The index you wish to set in local storage.
     * @param value The value you wish to set at the specified index.
     */
    this.set = function(key, value){
        var item = {"value":value};
        localStorage.setItem(key, JSON.stringify(item));
    }
    
    
    
     /**
     * Determines whether or not the specified key exists in localStorage.
     * @author Daniel Fairweather
     * @param key The index you wish to check in local storage.
     * @param {Boolean} Whether or not the specified key exists.
     */
    this.exists = function(key){
        var item = localStorage.getItem(key);
    
        if(item == undefined){
            console.log("Don't exist");
            return(false);
        }
        else{
            return(true);
        }
    }
}

var storage = new Storage();

function Background(){
    chrome.extension.onMessage.addListener(function(request, sender, sendResponse){
        switch(request.method){
            case "getExceptions":
               sendResponse({data: "Hello World"});
               break;
            case "notify":
                notify(request.safe, request.total, sender);
                break;
			case "getOptions":
				var options = getOptions();
                sendResponse({data: options});
				break;
			case "nExceptionCheck":
				var nExceptions = getNExceptions();
				sendResponse({data: nExceptions});
				break;
			// Will not be called
			// Nowhere in program is this called
			case "exceptionCheck":
				var exceptions = getExceptions();
				sendResponse({data: exceptions});
				break;
			// Will not be called
			// Nowhere in program is this called
			case "LExceptionsCheck":
				var LExceptions = getLExceptions();
				sendResponse({data: LExceptions});
				break;
        }
    });

    /**
	 *
	 */
	 this.notifInitial = function(){
		if(!storage.exists("notifications")){
			storage.set("notifications", true);
			storage.set("exceptions", "");
			storage.set("notificationexceptions", "");
			storage.set("linkexceptions", "");
			storage.set("clearcache", false);
		}
	 }
    
    /**
     * Displays an infobar to the user.
     * @author Sterling Rinehart
     * @param count The number of links which were changed.
     */
    var notify = function(safe, total, sender){
        var url = "infoBar.html#" + safe + "_" + total;
        chrome.experimental.infobars.show({
            tabId: sender.tab.id,
            path: url
        });
    }
	
	
	
	/**
	 *
	 */
	var getOptions = function(){
		var array = new Array();
		array[0] = storage.get("notifications");
		return(array);
	}
	
	var getNExceptions = function(){
		var array = storage.get("notificationexceptions");
		return(array);
	}
	
	var getExceptions = function(){
		var array = storage.get("exceptions");
		return(array);
	}
	
	var getLExceptions = function(){
		var array = storage.get("linkexceptions");
		return(array);
	}
}


var background = new Background();
background.notifInitial();

chrome.runtime.onSuspend.addListener(function() {
	if (storage.get("clearcache")) {
		storage.clearCerts();
	}
});
